package com.landleaf.smarthome.net.mqtt;

import android.content.Context;

import com.landleaf.smarthome.util.LogUtils;

import org.eclipse.paho.client.mqttv3.DisconnectedBufferOptions;
import org.eclipse.paho.client.mqttv3.IMqttActionListener;
import org.eclipse.paho.client.mqttv3.IMqttToken;
import org.eclipse.paho.client.mqttv3.MqttAsyncClient;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;

/**
 * When I wrote this, only God and I understood what I was doing
 * Now, God only knows
 * Created by 海航
 * 2020/9/25
 * 功能描述:
 */
public class MqttClient {
    private static volatile MqttClient singleton = null;
    private MqttAsyncClient mqtAsyncClient;
    private Context context;

    private MqttClient() {
    }

    public static MqttClient getInstance() {
        if (singleton == null) {
            synchronized (MqttClient.class) {
                if (singleton == null) {
                    singleton = new MqttClient();
                }
            }
        }
        return singleton;
    }

    public synchronized void connect() {
        if (isConnect() || mqtAsyncClient != null) {
            disConnect();
        }
        MqttConnectOptions mqttConnectOptions = new MqttConnectOptions();

        mqttConnectOptions.setCleanSession(true);
        mqttConnectOptions.setUserName(MqttConst.NAME);
        mqttConnectOptions.setPassword(MqttConst.PWD.toCharArray());
        // 设置超时时间 单位为秒
        mqttConnectOptions.setConnectionTimeout(10);
        // 设置会话心跳时间 单位为秒 服务器会每隔1.5*20秒的时间向客户端发送个消息判断客户端是否在线，但这个方法并没有重连的机制
        mqttConnectOptions.setKeepAliveInterval(20);
        //设置断开后重新连接
        mqttConnectOptions.setAutomaticReconnect(true);
        try {
            this.mqtAsyncClient = new MqttAsyncClient(MqttConst.MQTT_URL, "aa:bb:cc:dd:ee:ff", new MemoryPersistence());
            this.mqtAsyncClient.connect(mqttConnectOptions, null, new IMqttActionListener() {
                @Override
                public void onSuccess(IMqttToken asyncActionToken) {
                    LogUtils.d("连接成功");
                    DisconnectedBufferOptions disconnectedBufferOptions = new DisconnectedBufferOptions();
                    disconnectedBufferOptions.setBufferEnabled(true);
                    disconnectedBufferOptions.setBufferSize(1024);
                    disconnectedBufferOptions.setPersistBuffer(false);
                    disconnectedBufferOptions.setDeleteOldestMessages(false);
                    mqtAsyncClient.setBufferOpts(disconnectedBufferOptions);
                    subscribeTopic();
                }

                @Override
                public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
                    LogUtils.d("连接失败" + exception.getMessage());
                    reconnect();
                }
            });
            mqtAsyncClient.setCallback(new MqttMessageCallback());
        } catch (Exception e) {
            e.printStackTrace();
            reconnect();
            LogUtils.d("连接失败" + e.getMessage());
        }

    }

    /**
     * 重连
     */
    private void reconnect() {
        disConnect();
        connect();
    }

    /**
     * 订阅topic
     */
    private void subscribeTopic() {

        try {
            if (mqtAsyncClient != null)
                mqtAsyncClient.subscribe(MqttConst.COMMON_RESPONSE_TOPIC, MqttConst.COMMON_QOS, null, new IMqttActionListener() {
                    @Override
                    public void onSuccess(IMqttToken asyncActionToken) {

                    }

                    @Override
                    public void onFailure(IMqttToken asyncActionToken, Throwable exception) {

                    }
                });
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }


    public boolean isConnect() {
        boolean isConnect = false;
        if (mqtAsyncClient != null) {
            try {
                isConnect = mqtAsyncClient.isConnected();
            } catch (Exception e) {
                e.printStackTrace();
                isConnect = false;
            }
        }
        return isConnect;

    }


    /**
     * 发送消息
     *
     * @param publishMessage
     */
    public void publishMessage(String publishMessage) {
        try {
            MqttMessage message = new MqttMessage();
            message.setPayload(publishMessage.getBytes());
            if (mqtAsyncClient != null) {
                mqtAsyncClient.publish(MqttConst.COMMON_REQUEST_TOPIC, message, null, new IMqttActionListener() {
                    @Override
                    public void onSuccess(IMqttToken asyncActionToken) {
                        LogUtils.d("消息发送成功-->:"+publishMessage);
                    }

                    @Override
                    public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
                        LogUtils.d("消息发送失败");
                    }
                });
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void disConnect() {
        try {
            if (mqtAsyncClient != null) {
                mqtAsyncClient.disconnect();
                mqtAsyncClient.close();
                mqtAsyncClient = null;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
